require 'serverside'

ServerSide::Model.database = Postgres::Database.new(...)

class Nodes < ServerSide::Model
  translate :logged => :boolean, :state_stamp => :time
  
  def self.[](arg)
    case arg
    when String: find_by_path(arg.downcase)
    else find_by_id(arg)
    end
  end
  
  def self./(path)
    find_by_path("/#{path}")
  end
  
  class Record # < ServerSide::Model::Record < Hash
    query :parent {Nodes[@parent_id] if @parent_id}
    query :children {Nodes.filter_by_parent_id(@id)}
    query :subtree {Nodes.filter_by_path(/^#{@path}/)}

    query :producer {Channels[@producer_id] if @producer_id}
    query :consumers {Channels.consuming_node(@id)}
    
    before_delete do
      delete_children
      remove_from_producer if @producer_id
      remove_from_consumers
      remove_history
      remove_uac_references
    end
  end
end

###################################
n = Nodes/:cex1

###################################
node = Nodes[path]
XML.new(:reality) do
  node do
    path node[:path]
    value node[:value]
  end
end

###################################
Nodes.filter_by

class Channels < ServerSide::Model
  query :consumer_refs {join(:consumer_refs, :id => :channel_id)}

  query :consuming_node do |node_id|
    consumer_refs.filter(:consumer_refs__node_id => node_id)
  end
  
  query :stale {filter(:last_updated => Time.now - STALE_TIME)}
  
  query :remove_stale {stale.delete} # should be smart enough to know about before_delete
  
  class Record
    query :consumed_nodes {db[:consumer_refs].filter_by_channel_id(@id)}
    
    one_to_many :consumed_nodes, :table => :consumer_refs, :on => :channel_id
    
    query :produced_nodes {Nodes.filter_by_producer_id(@id)}
    
    before_delete {cleanup}
  end
end

n = Nodes

